package cn.frank.framework.king.rest;

/**
 * @description: TODO
 * @author: renjiangyang
 * @date 2025/10/28 15:53:58
 * @since 1.8
 */

import cn.frank.framework.king.domain.vo.Result;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @description: 可控制核心数的 CPU 高负载模拟
 */
@Api(tags = "CPU 多核心模拟开关")
@RestController
@Slf4j
@RequestMapping(value = "/api/test")
public class CpuStressController {

    private final AtomicBoolean running = new AtomicBoolean(false);
    private final List<Thread> threads = new ArrayList<>();

    @ApiOperation(value = "开启 CPU 高负载（可指定核心数）")
    @ApiOperationSupport(order = 1)
    @GetMapping("/cpu/start")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "duration", value = "持续时间(秒)", dataType = "Integer", defaultValue = "10", required = true),
            @ApiImplicitParam(name = "cores", value = "CPU 核心数", dataType = "Integer", defaultValue = "1", required = true)
    })
    public Result<String> startCpu(int duration, int cores) {
        // 如果已有 CPU 模拟在运行，则先停止原来的
        if (running.get()) {
            running.set(false);
            threads.forEach(t -> {
                try {
                    t.join();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
            threads.clear();
            log.info("CPU 高负载模拟已被新任务覆盖，停止旧的模拟");
        }

        running.set(true);
        threads.clear();

        int availableCores = Runtime.getRuntime().availableProcessors();
        if (cores > availableCores) {
            cores = availableCores;
        }

        for (int i = 0; i < cores; i++) {
            Thread t = new Thread(() -> {
                long end = System.currentTimeMillis() + duration * 1000L;
                while (running.get() && System.currentTimeMillis() < end) {
                    double x = Math.random();
                    for (int j = 0; j < 1000000; j++) {
                        x = Math.sin(x) * Math.tan(x);
                    }
                }
            }, "CPU-Stress-Thread-" + i);
            t.setDaemon(true);
            t.start();
            threads.add(t);
        }

        log.info("CPU 高负载模拟开始，持续 {} 秒，占用核心数：{}", duration, cores);
        return Result.success("CPU 高负载模拟已启动（覆盖旧任务），持续 " + duration + " 秒，占用核心数：" + cores);
    }


    /**
     * 停止 CPU 模拟
     */
    @ApiOperation(value = "停止 CPU 高负载")
    @ApiOperationSupport(order = 2)
    @GetMapping("/cpu/stop")
    public Result<String> stopCpu() {
        if (!running.get()) {
            return Result.fail("CPU 模拟未运行");
        }
        running.set(false);
        threads.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        threads.clear();
        log.info("CPU 高负载模拟被手动停止");
        return Result.success("CPU 高负载模拟已停止");
    }

    /**
     * 查询 CPU 模拟状态
     */
    @ApiOperation(value = "查询 CPU 模拟状态")
    @ApiOperationSupport(order = 3)
    @GetMapping("/cpu/status")
    public Result<String> cpuStatus() {
        return Result.success(running.get() ? "CPU 模拟正在运行" : "CPU 模拟已停止");
    }
}